import { UniversalCamera, Vector3 } from "@babylonjs/core";

export default class Player {

    private camera: UniversalCamera;
    /*
    0 = 不移动
    1 = 向前
    2 = 向后
    3 = 向左
    4 = 向右
     */
    private moveState = 0;
    private moveS = 0.07;
    private moveQueue: number[] = [];
    public static play: Player;


    public constructor(camera: UniversalCamera) {
        this.camera = camera;
        Player.play = this;
        this.init();
    }

    public start() {
        this.update(0);

    }

    private init() {
        document.onkeydown = this.keyDownEvent;
        document.onkeyup = this.keyUpEvent;
    }

    private move() {
        const { moveState, camera, moveS } = this;
        const { position: posi, target } = camera;
        //获得相机方向
        const f = target.clone().subtract(posi).normalize();
        //获取垂线方向
        const v = this.getCameraVertical();
        //求出左右两边向量
        const l = f.cross(v);
        const r = v.cross(f);

        switch (moveState) {
            case 1:
                camera.position.copyFrom(posi.clone().add(f.multiplyByFloats(moveS, moveS, moveS)));
                break;
            case 2:
                camera.position.copyFrom(posi.clone().add(f.multiplyByFloats(-moveS, -moveS, -moveS)));
                break;
            case 3:
                camera.position.copyFrom(posi.clone().add(l.multiplyByFloats(moveS, moveS, moveS)));
                break;
            case 4:
                camera.position.copyFrom(posi.clone().add(r.multiplyByFloats(moveS, moveS, moveS)));
                break;
            case 5:
                //camera.position.copyFrom(posi.clone().add(v.multiplyByFloats(moveS, moveS, moveS)));
                camera.position.copyFrom(posi.clone().add(new Vector3(0, 1, 0).multiplyByFloats(moveS, moveS, moveS)));
                break;
            case 6:
                // camera.position.copyFrom(posi.clone().add(v.multiplyByFloats(-moveS, -moveS, -moveS)));
                camera.position.copyFrom(posi.clone().add(new Vector3(0, 1, 0).multiplyByFloats(-moveS, -moveS, -moveS)));
                break;
        }
    }

    private updateMoveSate(state: number) {
        const { moveQueue } = this;
        this.moveState = state;
        //查询是否拥有
        const index = moveQueue.indexOf(state);
        if (index != -1) {
            moveQueue.splice(index, 1);
        }
        moveQueue.push(state);
    }

    private delMoveState(state: number) {
        const { moveQueue } = this;
        const index = moveQueue.indexOf(state);
        if (index != -1) {
            moveQueue.splice(index, 1);
            if (moveQueue.length > 0)
                this.moveState = moveQueue[moveQueue.length - 1];
            else
                this.moveState = 0;
        }
    }

    private keyDownEvent(e: KeyboardEvent) {
        switch (e.code) {
            case 'KeyW'://W
                Player.play.updateMoveSate(1);
                break;
            case 'KeyS'://S
                Player.play.updateMoveSate(2);
                break;
            case 'KeyA'://A
                Player.play.updateMoveSate(3);
                break;
            case 'KeyD'://D
                Player.play.updateMoveSate(4);
                break;
            case 'Space'://space
                Player.play.updateMoveSate(5);
                break;
            case 'ShiftLeft'://shift
                Player.play.updateMoveSate(6);
                break;
            case 'KeyQ'://输出相机位置
                const camera = Player.play.camera;
                console.log(camera.position, camera.getTarget())
                break;
        }

    }

    private keyUpEvent(e: KeyboardEvent) {
        switch (e.code) {
            case 'KeyW'://W
                Player.play.delMoveState(1);
                break;
            case 'KeyS'://S
                Player.play.delMoveState(2);
                break;
            case 'KeyA'://A
                Player.play.delMoveState(3);
                break;
            case 'KeyD'://D
                Player.play.delMoveState(4);
                break;
            case 'Space'://space
                Player.play.delMoveState(5);
                break;
            case 'ShiftLeft'://shift
                Player.play.delMoveState(6);
                break;
        }
    }

    private update(time: number) {
        this.move();
        requestAnimationFrame((time: number) => { this.update(time); });
    }

    private getCameraVertical() {
        const { x, y } = this.camera.rotation;
        const [curX, curY] = [(x - Math.PI - Math.PI / 2), (y + Math.PI / 2)];

        const position = new Vector3();
        position.copyFrom(new Vector3(
            1 * Math.cos(curX) * Math.cos(curY),
            1 * Math.sin(curX),
            1 * Math.cos(curX) * -Math.sin(curY)
        ));
        return position.normalize();
    }
}